import requests
from bs4 import BeautifulSoup
import csv
import datetime

url = 'https://www.bilibili.com/ranking'

# 发起网络请求
response = requests.get(url)

# 解析页面
soup = BeautifulSoup(response.text, 'html.parser')  # 参数1：页面源代码 参数2：解析方式


# print(soup.title.text)

# 存放爬取到的各种数据
class Video:

    # 构造函数
    def __init__(self, rank, title, score, author, author_id, video_url):
        self.rank = rank
        self.title = title
        self.score = score
        self.author = author
        self.author_id = author_id
        self.video_url = video_url

    # 定义一个用于存放表头的函数 静态方法无需self参数
    @staticmethod
    def table_head():
        return ['排名', '标题', '得分', 'Up主', 'Up主id', '视频链接']

    # 定义一个用于存放表体的函数
    def table_body(self):
        return [self.rank, self.title, self.score, self.author, self.author_id, self.video_url]


# 查找对应标签的内容
items = soup.findAll('li', {'class': 'rank-item'})  # 参数1：li标签 参数2：li标签下的属性class（键值对）
# print(len(items))

videos = []  # 用于存放Video对象

for itm in items:
    # 查找<li class="rank-item">下对应标签的内容   find只找符合要求的第一个
    title = itm.find('a', {'class': 'title'})  # 参数1：a标签 参数2：a标签下的属性class（键值对）
    rank = itm.find('div', {'class': 'num'})  # 参数1：div标签 参数2：div标签下的属性class（键值对）
    score = itm.find('div', {'class': 'pts'}).find(
        'div')  # 参数1：div标签 参数2：div标签下的属性class（键值对） .find('div')表示当前标签下的一个div标签
    author = itm.find_all('a')[2]  # 获取第3个a标签的内容

    space = itm.find_all('a')[2].get('href')  # 获取第3个a标签的内容，通过get获取href的内容
    author_id = space[len('//space.bilibili.com/'):]  # 截取href中//space.bilibili.com/后的一部分

    # video_url = itm.find_all('a')[1].get('href')  # 获取第2个a标签的内容，通过get获取href的内容
    video_url = itm.find('a', {'class': 'title'}).get('href')  # 第二种方式

    # 将数据存入Video的对象
    v = Video(rank.text, title.text, score.text, author.text, author_id, video_url)
    videos.append(v)

    # .text只获取文字
    print(rank.text + " " + title.text + " " + score.text + " " + author.text + " " + author_id + " " + video_url)

    # print(rank.text)
    # print(title.text)
    # print(score.text)

# 创建一个csv文件
now_date = datetime.datetime.now().strftime('%Y%m%d')  # 以时间作为文件名 .strftime('%Y%m%d')用于设置格式
file_name = f'top100_{now_date}.csv'
with open(file_name, 'w', newline='', encoding='utf-8-sig') as f:  # 以写的方式打开文件
    writer = csv.writer(f)  # 创建一个用于写数据的writer
    writer.writerow(Video.table_head())  # 调用静态函数写表头

    for v in videos:
        writer.writerow(v.table_body())
